/************************************************************************/
// Copyright (C) 2016, han_gangbiao. All rights reserved.
// Use of this source code is governed by a GPL-v2 license that can be found in the License file.
// 
// [Time]:      2016-3-20 16:43:50
// [Author]:    han_gangbiao [http://my.oschina.net/jackhen]
// [Info]:      
/************************************************************************/

#include "RPCClient.h"
#include <unistd.h>
#include <sys/syscall.h>
#define gettid() syscall(__NR_gettid)

CRPCClient::CRPCClient( const std::string& remote_ip, int remote_port, CRpcClientMgr* pMgr )
    :CRpcClientBase(pMgr)
{
    m_remote_ip = remote_ip;
    m_remote_port = remote_port;
    m_bOffline = true;
}

CRPCClient::~CRPCClient()
{
    printf("析构\n");
    stop_agent();
}

int CRPCClient::start_agent()
{
    int cli_fd = start_rpc_client(m_remote_ip.c_str(), m_remote_port);
    if(cli_fd < 0) {
        printf("start_rpc_client failed. remote[%s:%d]\n", m_remote_ip.c_str(), m_remote_port);
        return -1;
    }
    {
        smart::guard_t guard(&m_lock);
        m_bOffline = false;
        printf("reconn successfully, remote[%s:%d]\n", m_remote_ip.c_str(), m_remote_port);
    }
    return 0;
}

int CRPCClient::stop_agent()
{
    printf("%lu\n", gettid());
    stop_rpc_client();
    {
        smart::guard_t guard(&m_lock);
        m_bOffline = true;
    }
    printf("stop_agent ok....\n");
    return 0;
}

bool CRPCClient::isOffline()
{
    smart::guard_t guard(&m_lock);
    return m_bOffline;
}

int CRPCClient::on_invoke( smart::ref_ptr<NetBinaryPdu> pdu )
{
    printf("on_invoke: %s\n", pdu->getBody());
    NetBinaryPduRequest* request = dynamic_cast<NetBinaryPduRequest*>(pdu.getPointer());
    if(request == NULL)
    {
        pdu->setFlag(NET_PDU_RESPONSE);
        pdu->setBody("invalid request");
        invoke(pdu.getPointer());
        return 0;
    }
    smart::ref_ptr<NetBinaryPduResponse> response = request->createResponse();
    response->setBody("OK!");

    invoke(response.getPointer());
    return 0;
}

int CRPCClient::on_rpc_close( int errcode )
{
    printf("on_rpc_close errcode[%d]\n", errcode);
    stop_agent();
    return 0;
}



CAutoReconnSingleton::CAutoReconnSingleton()
{

}

CAutoReconnSingleton::~CAutoReconnSingleton()
{
    stop_run();
}

int CAutoReconnSingleton::start_run( const std::string& remote_ip, int remote_port, CRpcClientMgr* pMgr )
{
    m_pClient = new CRPCClient(remote_ip, remote_port, pMgr);
    start();
    return 0;
}

int CAutoReconnSingleton::stop_run()
{
    stop();
    m_pClient = NULL;
    return 0;
}

int CAutoReconnSingleton::run()
{
    printf("check offline...\n");
    if( m_pClient && (m_pClient->isOffline() == true) )
    {
        m_pClient->start_agent();
    }
    SLEEP_MS(3000);
    return 0;
}
